设置环境变量 (environments)
environments 是 Scripting 新增的视图修饰符,用于向当前视图树(View Hierarchy)注入特定的 environment values。
它的作用与 SwiftUI 的 .environment() 类似,但基于 Scripting 的设计进行了显式声明和类型收敛,避免隐式行为。
目前 environments 支持以下 environment 值:
editMode: 控制视图的编辑模式(如 List 的编辑状态)
openURL: 自定义打开链接(URL)的处理方式
这些 environment 值会影响其子视图中的行为与交互能力。
修饰符定义
1environments?: {
2 editMode?: Observable<EditMode>;
3 openURL?: (url: string) => OpenURLActionResult;
4};
一、editMode(编辑模式)
editMode 用于设置当前视图树中所有支持编辑模式的组件的编辑状态。
典型用途:
- 控制
List 的编辑状态
- 启用批量删除、移动操作
- 与用户交互同步(如切换编辑按钮)
类型定义
1class EditMode {
2 readonly value: "active" | "inactive" | "transient" | "unknown"
3 readonly isEditing: boolean
4
5 static active(): EditMode
6 static inactive(): EditMode
7 static transient(): EditMode
8}
value 含义
| 值 |
描述 |
active |
编辑模式已开启 |
inactive |
编辑模式已关闭 |
transient |
临时状态(如交互中切换) |
unknown |
非预期状态,通常不需使用 |
与 Observable 配合使用
由于 editMode 是动态值,必须使用 Observable<EditMode> 传递,以便视图随编辑状态变化而刷新。
editMode 使用示例
1const editMode = useObservable(() => EditMode.active())
2
3<List
4 environments={{
5 editMode: editMode
6 }}
7>
8 <ForEach
9 editActions="all"
10 data={items}
11 builder={item => <Text key={item.id}>{item}</Text>}
12 />
13</List>
说明:
- 将
editMode 设置到 List 的 environment 中
- List 中的
ForEach 会根据该状态启用、禁用删除/移动等编辑能力
- 修改
editMode.value 将自动刷新界面
二、openURL(自定义 URL 打开行为)
openURL environment 允许为当前视图树定义一套自定义的 URL 打开逻辑。
这会覆盖如 <Link>、Text(url:) 等组件的默认行为。
用途示例:
- 控制 URL 在 App 内打开还是系统浏览器打开
- 根据 URL 类型执行不同逻辑
- 拦截 URL 点击并进行验证或跳转处理
类型定义
1openURL?: (url: string) => OpenURLActionResult;
OpenURLActionResult
自定义 URL 打开逻辑的返回类型。
1class OpenURLActionResult {
2 type: string
3
4 static handled(): OpenURLActionResult
5 static discarded(): OpenURLActionResult
6
7 static systemAction(options?: {
8 url?: string
9 prefersInApp: boolean // Requires iOS26.0+
10 }): OpenURLActionResult
11}
作用说明
| 返回值 |
含义 |
handled() |
URL 已处理,不执行默认行为 |
discarded() |
忽略该 URL |
systemAction(options) |
要求系统打开给定 URL(支持 App 内或外打开) |
openURL 使用示例
1<Group
2 environments={{
3 openURL: (url) => {
4 return OpenURLActionResult.systemAction({
5 url,
6 prefersInApp: false
7 })
8 }
9 }}
10>
11 {urls.map(url =>
12 <Link url={url}>{url}</Link>
13 )}
14</Group>
说明:
- 所有
<Link> 均会交给自定义的 openURL 方法处理
- 示例将所有 URL 交由系统处理,并要求“非 App 内打开(prefersInApp: false)”
使用总结
| environment key |
类型 |
作用范围 |
使用场景 |
editMode |
Observable<EditMode> |
影响所有可编辑组件 |
List 编辑、批量操作 |
openURL |
(url) => OpenURLActionResult |
所有链接组件 |
自定义 URL 处理逻辑 |
完整示例:同时使用 editMode 与 openURL
1const editMode = useObservable(() => EditMode.inactive())
2
3<VStack
4 environments={{
5 editMode,
6 openURL: (url) => {
7 if (url.startsWith("https://safe.com")) {
8 return OpenURLActionResult.systemAction({ url, prefersInApp: true })
9 }
10 return OpenURLActionResult.discarded()
11 }
12 }}
13>
14 <Button
15 title="Toggle Edit"
16 action={() => {
17 editMode.value = editMode.value.isEditing
18 ? EditMode.inactive()
19 : EditMode.active()
20 }}
21 />
22
23 <List>
24 ...
25 </List>
26
27 <Link url="https://safe.com">Safe Link</Link>
28 <Link url="https://blocked.com">Blocked Link</Link>
29</VStack>
注意事项
environments 为局部作用域,仅影响其子视图。
editMode 必须是 Observable<EditMode> 才能触发界面更新。
openURL 若返回 handled(),将阻止默认行为。
systemAction 中的 prefersInApp 会影响是否在 App 内打开链接。
- 与 SwiftUI 不同,Scripting 的
environment 是显式声明,不会隐式传播所有 key。